/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.jtsmix.mixfile;

import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;

/**
 * counts CRC code from filename according to westwood logic
 * <p/>
 * Based on the Mix file format specification by Olaf van der Speck.
 *
 * @author halecivo
 */
public final class CRCCounter {

    private CRCCounter() {
    }

    /**
     * @param s    file name
     * @param game type of game
     * @return CRC file id
     */


    public static long getWestwoodCRC(String s, GameType game) {
        /*
         * TODO implement for TD, RA
         */
        StringBuilder name = new StringBuilder(s.toUpperCase());
        if (game != GameType.game_ts) { // for TD and RA
            int i = 0;
            long id = 0;
            int l = name.length(); // length of the filename
            while (i < l) {
                long a = 0;
                for (int j = 0; j < 4; j++) {
                    a >>= 8;
                    if (i < l) {
                        long shiftAndAdd = name.charAt(i);
                        a += (shiftAndAdd << 24);
                        if (a > 0xFFFFFFFFL) {
                            a -= 0xFFFFFFFFL;
                        }
                    }
                    i++;
                }
                id = (((id << 1) & 0xFFFFFFFF) | (id & 0xFFFFFFFF) >> 31) + a;
                if (id > 0xFFFFFFFFL) {
                    id -= 0xFFFFFFFFL;
                }
            }
            return id - 1;
        } else { // for TS
            int l = s.length();
            int a = l >>> 2;
            if ((l & 3) != 0) {
                name.append((char) (l - (a << 2)));
                int i = 3 - (l & 3);
                while ((i--) != 0) {
                    name.append(name.charAt(a << 2));
                }
            }
            return getCRCnum(name.toString());
        }
    }

    private static long getCRCnum(String s) {
        CRC32 crc = new CRC32();
        try {
            crc.update(s.getBytes("ASCII"));
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CRCCounter.class.getName()).log(Level.SEVERE, null, ex);
        }
        return crc.getValue();
    }

}
